home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’96 / DragClick / Sources / DragClick.cpp < prev    next >
C/C++ Source or Header  |  1996-06-21  |  5KB  |  264 lines

  1. // =============================================================================
  2. //
  3. //    InitUtils.cp
  4. //    
  5. //    Author: Greg Friedman
  6. //    Date:    MacHack '96
  7. //
  8. //    Do whatever you want with this source. Don't blame me if it doesn't work.
  9. //
  10. // =============================================================================
  11.  
  12.  
  13. #ifndef __A4STUFF__
  14. #include <A4Stuff.h>
  15. #endif
  16.  
  17. #ifndef __DRAG__
  18. #include <Drag.h>
  19. #endif
  20.  
  21. #ifndef __DRAGCLICK__
  22. #include "DragClick.h"
  23. #endif
  24.  
  25. #ifndef __CONSTANTS__
  26. #include "Constants.h"
  27. #endif
  28.  
  29. #ifndef __GESTALTSTUFF__
  30. #include "GestaltStuff.h"
  31. #endif
  32.  
  33. #ifndef __INITUTILS__
  34. #include "InitUtils.h"
  35. #endif
  36.  
  37. #ifndef __LAYERMGR__
  38. #include "LayerMgr.h"
  39. #endif
  40.  
  41. static UniversalProcPtr gOldTEClick;
  42. static OSType gDraggingProcess;
  43.  
  44. static void TEClickPatch();
  45. static Boolean TEClickPatchHandler(Point thePt, Boolean extend, TEHandle hTE);
  46. static void InstallTrackingPatchHandler();
  47. static asm void DragDispatchPatch();
  48.  
  49. void main()
  50. {
  51.     EnterCodeResource();
  52.     Handle    showInitResource = Get1Resource('Code', 7000);
  53.     if (showInitResource)
  54.         ((pascal void (*)(short, Boolean)) *showInitResource)(128, true);
  55.     
  56.     OSErr err = DetachInitResource(kDragClickResType, kDragClickResID);
  57.     InitializeLists();        
  58.     TEClickPatch();
  59.     DragDispatchPatch();
  60.     ExitCodeResource();
  61. }
  62.  
  63. static asm void TEClickPatch()
  64. {
  65.     move.w        #_TEClick, d0
  66.     _GetToolTrapAddress
  67.     lea            oldAddress, a1
  68.     move.l        a0, (a1)
  69.     
  70.     lea            patchhead, a0
  71.     move.w        #_TEClick, d0
  72.     _SetToolTrapAddress
  73.     rts
  74.     
  75. patchhead:
  76.     movem.l        d0-d2/a0-a1, -(sp)
  77.     move.l        24(sp), -(sp)            // push teHandle (5 saved regs + return addr)
  78.     move.b        32(sp), -(sp)            // push extend
  79.     move.l        36(sp), -(sp)            // push thePt
  80.     jsr            TEClickPatchHandler        // call c function
  81.     add.w        #10, sp                    // pop params
  82.     tst.b        d0
  83.     bne.s        dontcalloriginal
  84.     movem.l        (sp)+, d0-d2/a0-a1        // restore registers
  85.     move.l        oldAddress, -(sp)        // push old trap address
  86.     rts
  87.  
  88. dontcalloriginal:
  89.     movem.l        (sp)+, d0-d2/a0-a1
  90.     move.l        (sp),10(sp)
  91.     add.w        #10, sp
  92.     rts
  93.     
  94. oldAddress:
  95.     dc.l        0                        // storage for old address
  96. }
  97.  
  98. static asm void DragDispatchPatch()
  99. {
  100.     move.w    #_DragDispatch, d0
  101.     _GetToolTrapAddress
  102.     lea        oldAddress, a1
  103.     move.l    a0, (a1)
  104.     
  105.     lea        patchhead, a0
  106.     move.w    #_DragDispatch, d0
  107.     _SetToolTrapAddress
  108.     rts
  109.     
  110. patchhead:
  111.     cmp.w    #1, d0            // test selector for InstallTrackingHandler
  112.     bne.s    calloriginal
  113.     movem.l    d0-d2/a0-a1, -(sp)
  114.     jsr        InstallTrackingPatchHandler
  115.     movem.l (sp)+, d0-d2/a0-a1
  116.  
  117. calloriginal:
  118.     move.l    oldAddress, -(sp)
  119.     rts
  120.     
  121. oldAddress:
  122.     dc.l    0
  123. }
  124.  
  125. static Boolean TEClickPatchHandler(Point thePt, Boolean extend, TEHandle hTE)
  126. {
  127.     EnterCodeResource();
  128.     Boolean    result = FALSE;
  129.  
  130.     if (!extend && HasProcessMgr())
  131.     {
  132.         OSType curSig;
  133.         long ticks = TickCount();
  134.         
  135.         if (GetCurrentProcessSignature(&curSig) == noErr && (IsIncluded(curSig) || !IsExcluded(curSig)))
  136.         {
  137.             RgnHandle selectRgn = NewRgn();
  138.             
  139.             if (selectRgn)
  140.             {
  141.                 TEGetHiliteRgn(selectRgn, hTE);
  142.                 Point globalPt = thePt;
  143.                 LocalToGlobal(&globalPt);
  144.                 if (PtInRgn(thePt, selectRgn) && WaitMouseMoved(globalPt))
  145.                 {
  146.                     gDraggingProcess = curSig;
  147.                     DoDrag(thePt, selectRgn, hTE, ticks);
  148.                     result = TRUE;
  149.                 }
  150.                 
  151.                 DisposeRgn(selectRgn);
  152.             }
  153.         }
  154.     }
  155.         
  156.     ExitCodeResource();
  157.     return result;
  158. }
  159.  
  160. void DoDrag(Point thePt, RgnHandle selectRgn, TEHandle hTE, long ticks)
  161. {
  162.     RgnHandle tempRgn = NewRgn();
  163.     if (!tempRgn)
  164.         return;
  165.     
  166.     InitCursor();
  167.     
  168.     CopyRgn(selectRgn, tempRgn);
  169.     InsetRgn(tempRgn, 1, 1);
  170.     DiffRgn(selectRgn, tempRgn, selectRgn);
  171.     DisposeRgn(tempRgn);
  172.     
  173.         // globalize the region
  174.     Point offsetPt = {0, 0};
  175.     LocalToGlobal(&offsetPt);
  176.     OffsetRgn(selectRgn, offsetPt.h, offsetPt.v);
  177.     
  178.     OSErr             err;
  179.     DragReference    dragRef;
  180.     
  181.     err = NewDrag(&dragRef);
  182.     if (err != noErr)
  183.         return;
  184.  
  185.     Boolean wasLocked = FALSE;
  186.     
  187.     if (!(HGetState((*hTE)->hText) & kMemLockMask))
  188.     {
  189.         HLock((*hTE)->hText);
  190.         wasLocked = TRUE;
  191.     }
  192.         
  193.     err = AddDragItemFlavor(dragRef, 1, 'TEXT', &((*((*hTE)->hText))[(*hTE)->selStart]), (*hTE)->selEnd - (*hTE)->selStart, 0);
  194.     if (wasLocked)
  195.         HUnlock((*hTE)->hText);
  196.  
  197.     Handle styleHandle = (Handle)TEGetStyleScrapHandle(hTE);
  198.     if (styleHandle)
  199.     {
  200.         HLock(styleHandle);
  201.         AddDragItemFlavor(dragRef, 1, 'styl', *styleHandle, GetHandleSize(styleHandle), 0);
  202.         DisposeHandle(styleHandle);
  203.     }
  204.     
  205.     Rect itemBounds = (*selectRgn)->rgnBBox;
  206.     SetDragItemBounds(dragRef, 1, &itemBounds);
  207.     
  208.     EventRecord event;
  209.     
  210.     event.what = mouseDown;    // mock-up an event record
  211.     event.message = 0;
  212.     event.when = ticks;
  213.     event.where = thePt;
  214.     event.modifiers = 0;
  215.     
  216.     LocalToGlobal(&event.where);
  217.     
  218.     //SetDragInputProc(dragRef, LocalDragInputProc, NULL);
  219.     TrackDrag(dragRef, &event, selectRgn);
  220.         
  221.     DisposeDrag(dragRef);
  222. }
  223.  
  224. void InstallTrackingPatchHandler()
  225. {
  226.     EnterCodeResource();
  227.     OSType curSig;
  228.     if (GetCurrentProcessSignature(&curSig) == noErr)
  229.     {
  230.         if (!IsIncluded(curSig))
  231.             ExcludeCurrentProcess();
  232.     }
  233.     ExitCodeResource();
  234. }
  235.  
  236. pascal OSErr LocalDragInputProc(Point* mouse,
  237.                                 short* modifiers,
  238.                                 void* /* dragInputRefCon */,
  239.                                 DragReference /* theDragRef */)
  240. {
  241.     EnterCodeResource();
  242.     OSErr err = noErr;
  243.  
  244.     if ((*modifiers & btnState) == 0 && (gDraggingProcess == kFinderCreator))
  245.     {
  246.         short        windowPart;
  247.         WindowPtr    foundWindow;
  248.         LayerPtr    foundLayer = NULL;
  249.         
  250.         windowPart = FindLayerWindow(*mouse, &foundWindow);
  251.         if (windowPart == 3)
  252.             err = -1;
  253.         else if (foundWindow)
  254.         {
  255.             foundLayer = WindowLayer(foundWindow);
  256.             if (((LayerPeek)foundLayer)->layerInfo->creator == kFinderCreator)
  257.                 err = -1;
  258.         }
  259.     }
  260.     
  261.     ExitCodeResource();
  262.     return err;
  263. }
  264.